﻿Imports System.Xml
Imports Microsoft.Office.Interop

Public Class Gestor

#Region "Stephan"

    ''' <summary>
    ''' Realiza la asignación general de la bonificación de un empleado
    ''' </summary>
    ''' <param name="p_idUsuario">Id del usuario</param>
    ''' <param name="p_bonificacion">Bonificacion</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 13/06/2010, Modificado: 13/06/2010.</remarks>
    Public Shared Sub asignarBonificacionGeneral(ByVal p_idUsuario As String, ByVal p_bonificacion As Integer)
        Dim bonificacion As Double

        bonificacion = p_bonificacion / 100

        MultiBonificacion.asignarBonificacionGeneral(p_idUsuario, bonificacion)

    End Sub

    ''' <summary>
    ''' Realiza la asignación de las bonificaciones de la meta de un empleado
    ''' </summary>
    ''' <param name="p_idUsuario">Id del usuario</param>
    ''' <param name="p_bonificacion">porcentaje de la bonificación</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 13/06/2010, Modificado: 13/06/2010.</remarks>
    Public Shared Sub asignarBonificacionMetas(ByVal p_idUsuario As String, ByVal p_bonificacion As Integer)
        Dim bonificacion As Double

        bonificacion = p_bonificacion / 100

        MultiBonificacion.asignarBonificacionMeta(p_idUsuario, bonificacion)

    End Sub

    ''' <summary>
    ''' Generar un archivo XML, con los datos de las cuenta contables y los movimientos de estas.
    ''' </summary>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 16/06/2010, Modificado: 24/06/2010.</remarks>
    Public Shared Sub generarArchivoXML(ByVal p_path As String)
        Dim listaCuentaContables As New List(Of CuentaContable)

        Try

            Dim enc As System.Text.Encoding
            Dim objXMLTW As New XmlTextWriter(p_path, enc)
            objXMLTW.WriteStartDocument()
            objXMLTW.WriteStartElement("DocumentoXML")

            objXMLTW.WriteStartElement("Cuentas_Contables")

            listaCuentaContables = MultiCuentaContable.consultar("")

            For i As Integer = 0 To listaCuentaContables.Count - 1


                objXMLTW.WriteStartElement("Cuenta_Contable")

                objXMLTW.WriteStartElement("Codigo")
                objXMLTW.WriteString(listaCuentaContables(i).codigo)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Descripcion")
                objXMLTW.WriteString(listaCuentaContables(i).descripcion)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Saldo")
                objXMLTW.WriteString(listaCuentaContables(i).saldo)
                objXMLTW.WriteEndElement()

                Dim listaMovimientos As New List(Of Movimiento)

                listaMovimientos = MultiMovimiento.buscarMovimientos(listaCuentaContables(i).codigo)

                For j As Integer = 0 To listaMovimientos.Count - 1

                    objXMLTW.WriteStartElement("Movimiento")

                    objXMLTW.WriteStartElement("Codigo_Movimiento")
                    objXMLTW.WriteString(listaMovimientos(j).codigoMovimientoM)
                    objXMLTW.WriteEndElement()

                    objXMLTW.WriteStartElement("Fecha")
                    objXMLTW.WriteString(listaMovimientos(j).fechaM)
                    objXMLTW.WriteEndElement()

                    objXMLTW.WriteStartElement("Monto")
                    objXMLTW.WriteString(listaMovimientos(j).montoM)
                    objXMLTW.WriteEndElement()

                    objXMLTW.WriteStartElement("Tipo")
                    objXMLTW.WriteString(listaMovimientos(j).tipoM)
                    objXMLTW.WriteEndElement()

                    objXMLTW.WriteStartElement("Eliminado")
                    objXMLTW.WriteString(listaMovimientos(j).eliminadoM)
                    objXMLTW.WriteEndElement()

                    objXMLTW.WriteEndElement() 'Fin Movimiento
                Next

                objXMLTW.WriteEndElement() 'Fin cuenta contable


            Next

            objXMLTW.WriteEndElement() 'Fin cuentas_Contables

            '--------------------------------------------------------

            objXMLTW.WriteStartElement("Salarios")

            Dim listaSalarios As List(Of Salario) = MultiSalario.buscarSalarios()

            For k As Integer = 0 To listaSalarios.Count - 1


                objXMLTW.WriteStartElement("Salario")


                objXMLTW.WriteStartElement("Codigo_Empleado")
                objXMLTW.WriteString(listaSalarios(k).codigoEmpleadoS)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Fecha")
                objXMLTW.WriteString(listaSalarios(k).fechaS)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Salario_Bruto")
                objXMLTW.WriteString(listaSalarios(k).salarioBrutoS)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Salario_Neto")
                objXMLTW.WriteString(listaSalarios(k).salarioNetoS)
                objXMLTW.WriteEndElement()

                objXMLTW.WriteStartElement("Bono_Valor")
                objXMLTW.WriteString(listaSalarios(k).bonoValorS)
                objXMLTW.WriteEndElement()


                objXMLTW.WriteEndElement() ' Fin Salario

            Next

            objXMLTW.WriteEndElement() ' Fin Salarios


            objXMLTW.WriteEndElement() ' fin documentXML
            objXMLTW.WriteEndDocument() 'Fin del documento
            objXMLTW.Flush() 'Escribir al archivo
            objXMLTW.Close()

        Catch Ex As Exception

        End Try

    End Sub

    ''' <summary>
    ''' Agregar un nuevo movimiento movimiento.
    ''' </summary>
    ''' <param name="p_codCuentaContable">Codigo de la cuenta contable</param>
    ''' <param name="p_fecha">fecha del dia del movimiento</param>
    ''' <param name="p_monto">monto del movimiento</param>
    ''' <param name="p_tipoMovimiento">tipo de movimiento</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 16/06/2010, Modificado: 21/06/2010.</remarks>
    Public Shared Sub agregarMovimiento(ByVal p_codCuentaContable As String, ByVal p_fecha As Date, ByVal p_monto As Double, ByVal p_tipoMovimiento As String)
        Dim objCuentaContable As CuentaContable
        Dim saldoCuentaContable As Double

        MultiMovimiento.agregar(p_codCuentaContable, p_fecha, p_monto, p_tipoMovimiento)

        objCuentaContable = MultiCuentaContable.buscar(p_codCuentaContable)

        saldoCuentaContable = objCuentaContable.saldo

        If p_tipoMovimiento = "Debe" Then
            saldoCuentaContable = saldoCuentaContable - p_monto
        ElseIf p_tipoMovimiento = "Haber" Then
            saldoCuentaContable = saldoCuentaContable + p_monto
        End If

        MultiCuentaContable.modificar(p_codCuentaContable, objCuentaContable.descripcion, saldoCuentaContable)


    End Sub

    ''' <summary>
    ''' Realiza el aumento salarial de los puestos y niveles
    ''' </summary>
    ''' <param name="p_porcentajeAumento">Porcentaje del aumento</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 20/06/2010, Modificado: 20/06/2010.</remarks>
    Public Shared Sub aumentoSalarial(ByVal p_porcentajeAumento As Integer)
        Dim aumentoSalarial As Double = p_porcentajeAumento / 100
        Dim drPuesto As IDataReader = MultiPuesto.listarDR()
        Dim listaPuesto As New List(Of Puesto)


        While drPuesto.Read
            listaPuesto.Add(cargarPuesto(drPuesto))
        End While

        For i As Integer = 0 To listaPuesto.Count - 1

            Dim salarioAumentado As Double = calculoAumentoSalario(listaPuesto(i).Salario, aumentoSalarial)
            MultiPuesto.aumentoSalarial(salarioAumentado, listaPuesto(i).Codigo)

        Next

        Dim listaNiveles As New List(Of Nivel)
        listaNiveles = MultiNivel.buscarNiveles

        For i As Integer = 0 To listaNiveles.Count - 1

            Dim salarioMinimoAumentado As Double = calculoAumentoSalario(listaNiveles(i).SalarioMinimo, aumentoSalarial)
            Dim salarioMaximoAumentado As Double = calculoAumentoSalario(listaNiveles(i).SalarioMaximo, aumentoSalarial)
            MultiNivel.modificarSalarios(salarioMinimoAumentado, salarioMaximoAumentado, listaNiveles(i).Codigo)

        Next

    End Sub

    ''' <summary>
    ''' Convierte el manual de puesto en vites y los envia la multi para insertarlo a la base de datos
    ''' </summary>
    ''' <param name="p_manualPuesto">Manual de puesto</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 21/06/2010, Modificado: 21/06/2010.</remarks>
    Public Shared Sub cargarManualPuesto(ByVal p_manualPuesto As String)
        Dim manualPuesto() As Byte
        manualPuesto = Utils.object2Byte(p_manualPuesto)
        MultiConfiguracion.cargarManualPuesto(manualPuesto)
    End Sub

    ''' <summary>
    ''' Devuelve el manual de puesto como un documento word.
    ''' </summary>
    ''' <returns>Documento word.</returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 21/06/2010, Modificado: 21/06/2010.</remarks>
    Public Shared Function descargarManualPuesto() As Word.Document
        Return MultiConfiguracion.descargarManualPuesto()
    End Function

    ''' <summary>
    ''' Resive un número que representa el mes y lo envia al multi para conseguir la suma de los saldos netos de los empleados.
    ''' </summary>
    ''' <param name="p_mes">Valor numero del mes</param>
    ''' <returns>Double</returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 20/06/2010, Modificado: 20/06/2010.</remarks>
    Public Shared Function generarPlanilla(ByVal p_mes As Integer) As Double
        Return MultiSalario.aplicarPlanilla(p_mes)
    End Function

    ''' <summary>
    ''' Revisa si ya se ha echo el pago por el mes
    ''' </summary>
    ''' <returns>Boolean</returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 24/06/2010, Modificado: 28/06/2010.</remarks>
    Public Shared Function validarUltimoSalario() As Boolean
        Dim objSalario As Salario = Nothing
        Dim fechaActual As Date = Now.Date
        Dim resultadoFinal As Boolean = False
        Dim annoActual As Boolean = False
        Dim mesActual As Boolean = False

        objSalario = MultiSalario.buscarSalario()

        If fechaActual.Month = objSalario.fechaS.Month Then
            mesActual = True
        End If

        If fechaActual.Year = objSalario.fechaS.Year Then
            annoActual = True
        End If

        If annoActual = True And mesActual = True Then
            resultadoFinal = True
        End If

        Return resultadoFinal
    End Function

    ''' <summary>
    ''' Agrega el total del salario de un empleado, dependiendo en su total de ventas y su porcentaje de comicion
    ''' </summary>
    ''' <param name="p_ventas">Valor de las ventas</param>
    ''' <param name="p_comicion">porcentaje de comición</param>
    ''' <param name="p_codigoUsuario">Código del usuario</param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 30/06/2010, Modificado: 30/06/2010.</remarks>
    Public Shared Function calcularSalarioVariable(ByVal p_ventas As Double, ByVal p_comicion As Integer, ByVal p_codigoUsuario As String) As Double
        Dim comicion As Double = p_comicion / 100
        Dim salarioAIngresar As Double = p_ventas * comicion
        Dim salarioActual As Double = 0
        Dim objUsuario As Usuario = MultiUsuario.buscar(p_codigoUsuario)
        Dim objPuesto As Puesto = objUsuario.puesto

        If objPuesto.TipoSalario = 2 Then

            salarioActual = objPuesto.Salario
            salarioAIngresar = salarioActual + salarioAIngresar
        End If
        Return salarioAIngresar
    End Function

#Region "Realizar Pago"

    ''' <summary>
    ''' Realiza el calculo y movimientos referente a los pagos de los empleados
    ''' </summary>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 24/06/2010, Modificado: 28/06/2010.</remarks>
    Public Shared Sub realizarPagoFijo()
        Dim listaObjCargasSociales As List(Of CargasSociales)
        Dim listaUsuario As New List(Of Usuario)

        Dim totalPorcentajeCCSS As Double = 0
        Dim totalPorcentajeTrabajador As Double = 0
        Dim totalPorcentajeOtrosPatronos As Double = 0
        Dim totalPorcentajeOtrosTrabajador As Double = 0

        listaUsuario = MultiUsuario.buscarUsuariosSalarioFijo()
        listaObjCargasSociales = MultiCargasSociales.buscar()

        For i As Integer = 0 To listaUsuario.Count - 1
            Dim objPuesto As Puesto
            Dim salarioBase As Double
            Dim salarioNeto As Double
            Dim valorBonificacionTotal As Double
            Dim valorBonificacionMeta, valorBonificacionGeneral As Double
            Dim bonificacionMetas, bonificacionGeneral As Double
            Dim porcentajeCCSS As Double = 0
            Dim porcentajeTrabajador As Double = 0
            Dim porcentajeOtrosPatronos As Double = 0
            Dim porcentajeOtrosTrabajador As Double = 0

            objPuesto = listaUsuario(i).puesto

            salarioBase = objPuesto.Salario

            bonificacionMetas = MultiBonificacion.obtenerBonificacionMeta(listaUsuario(i).identificacion)
            bonificacionGeneral = MultiBonificacion.obtenerBonificacionGeneral(listaUsuario(i).identificacion)

            ' Calculo bonificaciones

            valorBonificacionMeta = salarioBase * bonificacionMetas

            valorBonificacionGeneral = salarioBase * bonificacionGeneral

            valorBonificacionTotal = valorBonificacionMeta + valorBonificacionGeneral


            ' Calculo porcentajes sociales, etc

            porcentajeCCSS = salarioBase * listaObjCargasSociales(0).porcentCCSS

            porcentajeTrabajador = salarioBase * listaObjCargasSociales(0).porcentTrab

            porcentajeOtrosPatronos = salarioBase * listaObjCargasSociales(0).otrosPatrono

            porcentajeOtrosTrabajador = salarioBase * listaObjCargasSociales(0).otrosTrabajador

            ' ----- Se guardan los valores en los totales
            totalPorcentajeCCSS += salarioBase * listaObjCargasSociales(0).porcentCCSS

            totalPorcentajeTrabajador += salarioBase * listaObjCargasSociales(0).porcentTrab

            totalPorcentajeOtrosPatronos += salarioBase * listaObjCargasSociales(0).otrosPatrono

            totalPorcentajeOtrosTrabajador += salarioBase * listaObjCargasSociales(0).otrosTrabajador

            ' Calculo salario neto

            salarioNeto = salarioBase

            salarioNeto -= porcentajeCCSS
            salarioNeto -= porcentajeTrabajador
            salarioNeto -= porcentajeOtrosPatronos
            salarioNeto -= porcentajeOtrosTrabajador

            salarioNeto += valorBonificacionTotal

            ' Se guarda el registro

            MultiSalario.registrar(listaUsuario(i).identificacion, Now.Date, salarioBase, salarioNeto, valorBonificacionTotal)


        Next

        agregarMovimiento(0, Now.Date, totalPorcentajeCCSS, "Debe")
        agregarMovimiento(1, Now.Date, totalPorcentajeTrabajador, "Debe")
        agregarMovimiento(2, Now.Date, totalPorcentajeOtrosPatronos, "Debe")
        agregarMovimiento(3, Now.Date, totalPorcentajeOtrosTrabajador, "Debe")

    End Sub

    ''' <summary>
    ''' Realiza el pago de los usuarios que poseen un salario variable
    ''' </summary>
    ''' <param name="p_listaUsuarios"></param>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 06/07/2010, Modificado: 06/07/2010.</remarks>
    Public Shared Sub realizarPagoVariables(ByVal p_listaUsuarios As List(Of Object))
        Dim listaObjCargasSociales As List(Of CargasSociales)
        Dim listaUsuario As List(Of Object) = p_listaUsuarios

        Dim totalPorcentajeCCSS As Double = 0
        Dim totalPorcentajeTrabajador As Double = 0
        Dim totalPorcentajeOtrosPatronos As Double = 0
        Dim totalPorcentajeOtrosTrabajador As Double = 0

        listaObjCargasSociales = MultiCargasSociales.buscar()

        For i As Integer = 0 To p_listaUsuarios(0).Count - 2

            Dim salarioBase As Double
            Dim salarioNeto As Double
            Dim valorBonificacionTotal As Double
            Dim valorBonificacionMeta, valorBonificacionGeneral As Double
            Dim bonificacionMetas, bonificacionGeneral As Double
            Dim porcentajeCCSS As Double = 0
            Dim porcentajeTrabajador As Double = 0
            Dim porcentajeOtrosPatronos As Double = 0
            Dim porcentajeOtrosTrabajador As Double = 0

            salarioBase = p_listaUsuarios(1)(i)

            bonificacionMetas = MultiBonificacion.obtenerBonificacionMeta(listaUsuario(0)(i))
            bonificacionGeneral = MultiBonificacion.obtenerBonificacionGeneral(listaUsuario(0)(i))

            ' Calculo bonificaciones

            valorBonificacionMeta = salarioBase * bonificacionMetas

            valorBonificacionGeneral = salarioBase * bonificacionGeneral

            valorBonificacionTotal = valorBonificacionMeta + valorBonificacionGeneral


            ' Calculo porcentajes sociales, etc

            porcentajeCCSS = salarioBase * listaObjCargasSociales(0).porcentCCSS

            porcentajeTrabajador = salarioBase * listaObjCargasSociales(0).porcentTrab

            porcentajeOtrosPatronos = salarioBase * listaObjCargasSociales(0).otrosPatrono

            porcentajeOtrosTrabajador = salarioBase * listaObjCargasSociales(0).otrosTrabajador

            ' ----- Se guardan los valores en los totales
            totalPorcentajeCCSS += salarioBase * listaObjCargasSociales(0).porcentCCSS

            totalPorcentajeTrabajador += salarioBase * listaObjCargasSociales(0).porcentTrab

            totalPorcentajeOtrosPatronos += salarioBase * listaObjCargasSociales(0).otrosPatrono

            totalPorcentajeOtrosTrabajador += salarioBase * listaObjCargasSociales(0).otrosTrabajador

            ' Calculo salario neto

            salarioNeto = salarioBase

            salarioNeto -= porcentajeCCSS
            salarioNeto -= porcentajeTrabajador
            salarioNeto -= porcentajeOtrosPatronos
            salarioNeto -= porcentajeOtrosTrabajador

            salarioNeto += valorBonificacionTotal

            ' Se guarda el registro

            MultiSalario.registrar(listaUsuario(0)(i), Now.Date, salarioBase, salarioNeto, valorBonificacionTotal)


        Next

        agregarMovimiento(0, Now.Date, totalPorcentajeCCSS, "Debe")
        agregarMovimiento(1, Now.Date, totalPorcentajeTrabajador, "Debe")
        agregarMovimiento(2, Now.Date, totalPorcentajeOtrosPatronos, "Debe")
        agregarMovimiento(3, Now.Date, totalPorcentajeOtrosTrabajador, "Debe")

    End Sub

    ''' <summary>
    ''' Realiza la busqueda de aquellos empleados que poseen un salario variable
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 06/07/2010, Modificado: 06/07/2010.</remarks>
    Public Shared Function buscarEmpleadosTipoVariables() As List(Of Hashtable)
        Dim usuarios As New List(Of Hashtable)
        Dim usuarioTemp As Hashtable
        Dim usuariosObj As List(Of Usuario)

        usuariosObj = MultiUsuario.buscarUsuarioPorTipoVariable()

        For Each usuario As Usuario In usuariosObj
            Dim nombreDepartamento As String = Nothing

            usuarioTemp = usuario.toHashtable

            usuarios.Add(usuarioTemp)
        Next

        Return usuarios
    End Function

#End Region

#Region "Sistema"

    ''' <summary>
    ''' Resive un salario que desea aumentar y el valor por cuanto lo quiere aumentar, realiza el calculo y devuelve el salario aumentado
    ''' </summary>
    ''' <param name="p_salario">salario</param>
    ''' <param name="p_aumentoSalarial">valor del aumento</param>
    ''' <returns>Double</returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 20/06/2010, Modificado: 20/06/2010.</remarks>
    Private Shared Function calculoAumentoSalario(ByVal p_salario As Double, ByVal p_aumentoSalarial As Double) As Double
        Dim salarioAumentado As Double = p_salario
        Dim cantidadAumento As Double

        cantidadAumento = p_salario * p_aumentoSalarial

        salarioAumentado = salarioAumentado + cantidadAumento

        Return salarioAumentado

    End Function

    ''' <summary>
    ''' Resive un data reader de puesto y crea un objeto puesto
    ''' </summary>
    ''' <param name="dr">Un data reader de puesto</param>
    ''' <returns>Puesto</returns>
    ''' <remarks>Creador por: Stephan Endres, Fecha: 20/06/2010, Modificado: 20/06/2010.</remarks>
    Private Shared Function cargarPuesto(ByVal dr As IDataReader) As Puesto
        Dim objPuesto As Puesto
        With dr
            objPuesto = New Puesto(CInt(.Item("codigo")), CStr(.Item("nombre")), CStr(.Item("descripcion")), CInt(.Item("codigo_nivel")), CInt(.Item("tipo_salario")), CDbl(.Item("salario")))
        End With
        Return objPuesto
    End Function

#End Region

#End Region

#Region "Elías"

    ''' <summary>
    ''' Obtiene los datos del usuario actual.
    ''' </summary>
    ''' <returns>Datos del usuario.</returns>
    ''' <remarks>Creado por: Elías Baldioceda, Fecha: 20/06/2010, Modificado: 20/06/2010</remarks>
    Public Shared Function usuarioActual() As Hashtable
        Return g_usuario.toHashtable
    End Function


    ''' <summary>
    ''' Verifica si el usuario tiene el permiso indicado.
    ''' </summary>
    ''' <param name="p_identificacion">Número de identificación.</param>
    ''' <param name="p_permiso">Código del permiso.</param>
    ''' <returns>Si el usuario tiene el permiso.</returns>
    ''' <remarks>Creado por: Elías Baldioceda, Fecha: 27/04/2010, Modificado: 27/04/2010</remarks>
    Public Shared Function usuarioTienePermiso(ByVal p_identificacion As String, ByVal p_permiso As Integer) As Boolean
        Dim tiene As Boolean = False

        If p_identificacion <> Nothing Then
            tiene = MultiUsuario.tienePermiso(p_identificacion, p_permiso)
        End If

        Return tiene
    End Function

#End Region

End Class
